package com.jeff.android.lab;

import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.os.Bundle;

import androidx.multidex.MultiDex;
import androidx.startup.AppInitializer;

import com.alibaba.android.arouter.launcher.ARouter;
import com.jack.network.NetworkManager;
import com.jeff.android.lab.commonlib.AppConfig;
import com.jeff.android.lab.commonlib.IAppComponent;
import com.jeff.android.lab.jetpack.startup.ARouterInitializer;
import com.jeff.android.lab.jetpack.startup.NetworkManagerInitializer;
import com.jeff.android.lab.jframework.RuntimeManager;
import com.jeff.android.lab.jframework.app.BaseApplication;
import com.tencent.mmkv.MMKV;

import java.lang.ref.WeakReference;
import java.util.LinkedList;
import java.util.List;

/**
 * @author: duff
 * @date: 2018/12/26
 * @since: 1.0.0
 */
public class AppApplication extends BaseApplication implements IAppComponent {

    private static AppApplication sInstance;

    private List<WeakReference<Activity>> mActivityRefs =
            new LinkedList<>();

    @Override
    public void onCreate() {
        super.onCreate();
        RuntimeManager.instance().init(this, BuildConfig.VERSION_NAME, "jeff");

        initialize(this);

        AppInitializer.getInstance(this)
                .initializeComponent(NetworkManagerInitializer.class);

        AppInitializer.getInstance(this)
                .initializeComponent(ARouterInitializer.class);

        registerActivityLifecycleCallbacks(activityLifecycleCallbacks);
    }

    @Override
    public void initialize(Application app) {
        sInstance = (AppApplication) app;
        for (String comp : AppConfig.COMPONENTS) {
            try {
                Class<?> clazz = Class.forName(comp);
                Object object = clazz.newInstance();
                if (object instanceof IAppComponent) {
                    ((IAppComponent) object).initialize(this);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onTerminate() {
        super.onTerminate();
        ARouter.getInstance().destroy();
    }

    @Override
    protected void attachBaseContext(Context base) {
        super.attachBaseContext(base);
        MultiDex.install(this);
    }

    public static AppApplication getInstance() {
        return sInstance;
    }

    Application.ActivityLifecycleCallbacks activityLifecycleCallbacks =
            new ActivityLifecycleCallbacks() {
                @Override
                public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                    mActivityRefs.add(new WeakReference<>(activity));
                }

                @Override
                public void onActivityStarted(Activity activity) {

                }

                @Override
                public void onActivityResumed(Activity activity) {

                }

                @Override
                public void onActivityPaused(Activity activity) {

                }

                @Override
                public void onActivityStopped(Activity activity) {

                }

                @Override
                public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

                }

                @Override
                public void onActivityDestroyed(Activity activity) {
                    for (int i = mActivityRefs.size() - 1; i >= 0; i--) {
                        WeakReference<Activity> ref = mActivityRefs.get(i);
                        if (ref != null &&
                                activity == ref.get()) {
                            mActivityRefs.remove(ref.get());
                            break;
                        }
                    }
                }
            };

    public boolean isRunning() {
        for (WeakReference<Activity> ref : mActivityRefs) {
            final Activity activity = ref.get();
            if (activity != null && activity.getClass().equals(MainActivity.class)) {
                return true;
            }
        }
        return false;
    }

}
